/*
 * @(#)FdDao.java May 8, 2007
 * 
 * Copyright 2007 by ChinanetCenter Corporation.
 *
 * All rights reserved.
 *
 * This software is the confidential and proprietary information of
 * ChinanetCenter Corporation ("Confidential Information").  You
 * shall not disclose such Confidential Information and shall use
 * it only in accordance with the terms of the license agreement
 * you entered into with ChinanetCenter.
 * 
 */
package com.cnc.fd.service;

import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang.StringUtils;
import com.cnc.bas.db.HiberDao;
import com.cnc.bas.db.JdbcDao;
import com.cnc.bas.query.PageInfo;
import com.cnc.bas.query.QuerySql;
import com.cnc.bas.util.Log;
import com.cnc.bas.util.StringUtil;
import com.cnc.bas.util.UuidGenerator;
import com.cnc.fd.Constants;
 
import com.cnc.fd.hiber.FdFile;
import com.cnc.fd.hiber.FdManualTask;
 
import com.cnc.fd.hiber.FdRouteMap;
import com.cnc.fd.hiber.FdTaskList;
import com.cnc.fd.util.DateUtil;




/**
 * @author 阿闲
 * @date   May 8, 2007
 * @version 1.0
 */
public class FdDao {
	
	public static final String BEAN_ID = "fdDao";
	private Log log = Log.getLogger(this.getClass());
	private JdbcDao jdbcDao;
	private HiberDao hiberDao;
	
	
	public FdFile getFile(String fileId){
		
		return (FdFile)hiberDao.get(FdFile.class, fileId);
		
	}
	
	/**
	 * 通过名称查询文件
	 * @param fileName
	 * @return
	 */
	public FdFile getFileByName(String entername, String fileName){
		String hql = "from FdFile where entername=? and filename=? order by uploadTime desc";
		List list = hiberDao.find(hql, new Object[]{entername, fileName});
		if(list != null && list.size() > 0){
			return (FdFile)list.get(0);
		}
		return null;
	}
	 
	
	/**
	 * 查询有等待同步任务的客户信息
	 * 
	 * @return
	 */
	public List getWaitCustomerInfo(){
		
		StringBuffer sql = new StringBuffer("select tmp.entername as customer, if(fcc.priority is null,?,fcc.priority) as priority,");
		
		sql.append("if(fcc.allowOtherTaskCount is null, ?, fcc.allowOtherTaskCount) as allowOtherTaskCount,");
		sql.append("if(fcc.allowUploadTaskCount is null, ?, fcc.allowUploadTaskCount) as allowUploadTaskCount,");
		sql.append("if(fcc.newTaskFirst is null, 'N', fcc.newTaskFirst) as newTaskFirst ");
		sql.append("from (select distinct entername from FD_Task_List where taskStatus='wait')tmp ");
		sql.append("left join FD_Customer_Config fcc on fcc.customer=tmp.entername ");
		sql.append("order by priority;");
		
		Object[] values = {Constants.DEFAULT_CUSTOMER_PRIORITY, Constants.DEFAULT_CUSTOMER_OTHER_TASK_COUNT, Constants.DEFAULT_CUSTOMER_UPLOAD_TASK_COUNT};
		
		return jdbcDao.queryForList(sql.toString(), values);
		
	}
	
	/**
	 * 根据客户查询需要上传的同步任务
	 * @param entername 客户名称
	 * @param count 查询记录数
	 * @param isDesc 是否按时间降序
	 * @return
	 */
	public List getUploadWaitTaskByCustomer(String entername, int count, String isDesc){
		
		StringBuffer hql = new StringBuffer("from FdTaskList as o where o.taskKind='upload' and o.taskStatus='wait'");
		
		hql.append(" and o.entername='");
		
		hql.append(entername);
		
		if(isDesc.equals("Y")){
			hql.append("' order by o.timestamp desc");
		}else{
			hql.append("' order by o.timestamp");
		}
		
		
		return hiberDao.selectPages(hql.toString(), 0, count);
	}
	/**
	 * 根据客户查询需要同步的其他任务
	 * @param entername
	 * @param count
	 * @param isDesc
	 * @return
	 */
	public List getOtherWaitTaskByCustomer(String entername, int count, String isDesc){
		
		StringBuffer hql = new StringBuffer("from FdTaskList as o where o.taskKind!='upload' and o.taskStatus='wait'");
		
		hql.append(" and o.entername='");
		
		hql.append(entername);
		
		if(isDesc.equals("Y")){
			hql.append("' order by o.timestamp desc");
		}else{
			hql.append("' order by o.timestamp");
		}
		
		
		return hiberDao.selectPages(hql.toString(), 0, count);
	}
	
	/**
	 * 根据文件名判断相关的上传同步任务是否完成
	 * @param filename
	 * @return
	 */
	private boolean isRelUploadTaskFinish(String filename){
		String sql = "select count(*) as total from FD_Task_List where taskStatus in(?,?) and taskKind=? and filename=?";
		Object[] values = {Constants.TASK_STATUS_WAIT, Constants.TASK_STATUS_RUN, 
				Constants.TASK_KIND_UPLOAD, filename};
		long count = jdbcDao.queryForLong(sql, values);
		if(count > 0)
			return false;
		return true;
		
	}
	
	 
	 
	//根据客户获取文件用户组属性信息
	public String getFileAttributeByCustomer(String entername){
		String sql = "select fileAttribute from FD_Customer_Config where customer=?";
		Object[] values = {entername};
		Map map = jdbcDao.queryForMap(sql, values);
		if(null==map)
			return "root";
		return map.get("fileAttribute").toString();
	}
	/**
	 * 更新任务列表的任务状态(任务开始)
	 * @param taskId
	 * @param taskStatus
	 */
	public void updateTaskStartStatus(String taskId){
		String sql = "update FD_Task_List set taskStatus=?, syncStartTime=now() where taskId=? and taskStatus=?";
		Object[] values = {Constants.TASK_STATUS_RUN, taskId, Constants.TASK_STATUS_WAIT};
		jdbcDao.update(sql, values);
	}	

	/**
	 * 根据客户登陆名称，获取客户id
	 * 首先判断客户是否有映射关系 
	 * @param entername
	 * @return
	 */
	public String getCustomerIdByEntername(String entername){
		
		//根据映射文件，对entername进行映射
		//String newname = UserProperty.getEntername(entername);
		
		String newname = this.getMapEntername(entername);
		
		if(newname!=null)
			entername = newname;
		
		String sql = "select customerId from FD_Customer where entername=?";
		Object[] values = {entername};
		Map map = jdbcDao.queryForMap(sql, values);
		if(map == null)
			throw new RuntimeException("查询不到客户，entername：" + entername);
		return (String)map.get("customerId");
	}
	

	
	/**
	 * 根据客户id获取登陆名
	 * @param customerId
	 * @return
	 */
	public String getEnternameByCustomerId(String customerId){
		String sql = "select entername from FD_Customer where customerId=?";
		Object[] values = {customerId};
		Map map = jdbcDao.queryForMap(sql, values);
		if(map == null)
			throw new RuntimeException("查询不到登陆名，customerid：" + customerId);
		return (String)map.get("entername");
	}
	
	
	
	/**
	 * 根据客户id获取，下载服务器 
	 * @param customerId
	 * @return
	 */
	public List getServersByCustomer(String customerId){		
		
		String sql = "select a.serverId, a.serverName, a.ip, a.carryCompany, a.dataFull from FD_Down_Server a, FD_Customer_Server b where b.customerId=? and a.serverId=b.serverId and a.active=?";
		Object[] values = {customerId, Constants.SERVER_ACTIVE_TRUE};
		List list = jdbcDao.queryForList(sql, values);		
		
		return list;		
	}
	
	/**
	 * 根据客户登陆名，获取下载服务器
	 * @param entername
	 * @return
	 */
	public List getServersByEntername(String entername){
		String customerId = this.getCustomerIdByEntername(entername);
		return this.getServersByCustomer(customerId);
	}
	
	public String getCarryCompanyByIp(String ip){
		String sql = "select distinct carryCompany from FD_Down_Server where ip=?";
		Object[] values = {ip};
		Map map = jdbcDao.queryForMap(sql, values);
		if(map == null)
			throw new RuntimeException("查询不到运营商,ip："+ip);
		return (String)map.get("carryCompany");
	}
	
	 
	/**
	 * 根据客户id，获取客户下载服务器的所有运营商
	 * @param customerId
	 * @return
	 */
	public List getCarryCompanyByCustomer(String customerId){
		List result = new ArrayList();
		String sql = "select distinct a.carryCompany from FD_Down_Server a, FD_Customer_Server b where a.serverId=b.serverId and b.customerId=? and a.active=?";
		Object[] values = {customerId, Constants.SERVER_ACTIVE_TRUE};
		List list = jdbcDao.queryForList(sql, values);
		if(list == null || list.size() == 0)
			throw new RuntimeException("查询不到运营商");
		for(int i=0; i<list.size(); i++){
			Map map = (Map)list.get(i);
			result.add(map.get("carryCompany"));
		}
		return result;
	}
	
	/**
	 * 根据客户id和运营商，获取客户的机房
	 * @param customerId
	 * @return
	 */
	public List getNodeByCustomerAndCarryCompany(String customerId, String carryCompany){
		List result = new ArrayList();
		String sql = "select distinct a.nodeId from FD_Down_Server a, FD_Customer_Server b where a.serverId=b.serverId and b.customerId=? and a.carryCompany=? and a.active=?";
		Object[] values = {customerId, carryCompany, Constants.SERVER_ACTIVE_TRUE};
		List list = jdbcDao.queryForList(sql, values);
		if(list == null || list.size() == 0)
			throw new RuntimeException("查询不到机房，carryCompany="+carryCompany);
		for(int i=0; i<list.size(); i++){
			Map map = (Map)list.get(i);
			result.add(map.get("nodeId"));
		}
		return result;
	}
	
	/**
	 * 获取某一客户，某一运营商，某一机房内的机器
	 * @param customerId
	 * @param carryCompany
	 * @param nodeId
	 * @return
	 */
	public List getServerByCustomerCarrycompanyNode(String customerId, String carryCompany, String nodeId){
		
		String sql = "select a.serverId, a.serverName, a.ip, a.password, a.port from FD_Down_Server a, FD_Customer_Server b where a.serverId=b.serverId and b.customerId=? and a.carryCompany=? and a.nodeId=? and a.active=?";
		Object[] values = {customerId, carryCompany, nodeId, Constants.SERVER_ACTIVE_TRUE};
		List list = jdbcDao.queryForList(sql, values);	
		if(list == null || list.size() == 0)
			throw new RuntimeException("机房内查询不到机器");
		return list;
	}
	
	/**
	 * 获取未同步的下载服务器ip
	 * @param taskId
	 * @return
	 */
	public List getUnSyncServerIp(String taskId){
		String sql = "select ip from FD_Task_Detail where taskId=? and syncStatus=?";
		Object[] values = {taskId, Constants.SYNC_STATUS_UN_SYNC};
		List list = jdbcDao.queryForList(sql, values);
		List result = new ArrayList();
		for(int i=0; i<list.size(); i++){
			Map map = (Map)list.get(i);
			result.add(map.get("ip"));
		}
		return result;
	}
	
	/**
	 * 获取正在同步的下载服务器ip
	 * @param taskId
	 * @return
	 */
	public List getCurSyncServerIp(String taskId){
		String sql = "select ip from FD_Task_Detail where taskId=? and syncStatus=?";
		Object[] values = {taskId, Constants.SYNC_STATUS_CUR_SYNC};
		List list = jdbcDao.queryForList(sql, values);
		List result = new ArrayList();
		for(int i=0; i<list.size(); i++){
			Map map = (Map)list.get(i);
			result.add(map.get("ip"));
		}
		return result;
	}	
	
	
	/**
	 * 其它任务，是否同步结束
	 * @param taskId
	 * @return
	 */
	public boolean isSyncOver(String taskId){
		String sql = "select id from FD_Task_Detail where taskId=? and (syncStatus=? or syncStatus=?)";
		Object[] values = {taskId, Constants.SYNC_STATUS_UN_SYNC, Constants.SYNC_STATUS_CUR_SYNC};
		List list = jdbcDao.queryForList(sql, values);
		if(list==null || list.size()==0)
			return true;
		return false;
	}
	
	/**
	 * 其它任务同步，是否同步成功
	 * @param taskId
	 * @return
	 */
	public boolean isSyncSuccess(String taskId){
		String sql = "select id from FD_Task_Detail where taskId=? and syncStatus!=?";
		Object[] values = {taskId, Constants.SYNC_STATUS_HAS_SYNC};
		List list = jdbcDao.queryForList(sql, values);
		if(list==null || list.size()==0)
			return true;
		return false;
	}
	
	/**
	 * 其它任务，同步超时，将正在同步的机器的状态改为同步失败
	 * @param taskId
	 */
	public void updateTimeoutSyncStatus(String taskId){
		String sql = "update FD_Task_Detail set syncStatus=?, syncEndTime=? where taskId=? and syncStatus=?";
		Object[] values = {Constants.SYNC_STATUS_FAL_SYNC, new Date(), taskId, Constants.SYNC_STATUS_CUR_SYNC};
		jdbcDao.update(sql, values);
	}
	
	 
	
	/**
	 * 任务发起失败，清楚任务明细
	 * @param taskId
	 */
	public void deleteTaskDetail(String taskId){
		String sql = "delete from FD_Task_Detail where taskId=?";
		Object[] values = {taskId};
		jdbcDao.update(sql, values);
	}
	
	/**
	 * 删除重复的结果
	 * @param filename
	 */
	public void deleteRepeatRsynReslut(String filename, String customer){
		String sql = "select taskId from FD_Task_List where filename=? and entername=?";
		Object[] values = {filename, customer};
		Map map = jdbcDao.queryForMap(sql, values);
		if(map != null){
			sql = "delete from FD_Task_List where taskId=?";
			values = new Object[]{(String)map.get("taskId")};
			jdbcDao.update(sql, values);
			
			sql = "delete from FD_Task_Detail where taskId=?";
			jdbcDao.update(sql, values);
		}
	}
	
	/**
	 *  获取任务的状态
	 * @param taskId
	 * @return
	 */
	public String getSyncStatusById(String taskId){
		String sql = "select taskStatus from FD_Task_List where taskId=?";
		Object[] values = {taskId};
		Map map = jdbcDao.queryForMap(sql, values);
		//如果没有查到，或许同步任务还没生成
		if(map == null)
			return "";
		return (String)map.get("taskStatus");
	}
	
	/**
	 * 文件改名
	 * @param customer
	 * @param oldName
	 * @param newName
	 */
	public void renameFile(String customer, String oldName, String newName){
		String sql = "update FD_File set filename=? where entername=? and filename=?";
		Object[] values = {newName, customer, oldName};
		jdbcDao.update(sql, values);
	}
	
	/**
	 * 删除文件
	 * @param customer
	 * @param filename
	 */
	public void deleteFile(String customer, String filename){
		
		String sql = "delete from FD_File where entername=? and filename=?";
		
		Object[] values = {customer, filename};
		
		jdbcDao.update(sql, values);
	}
	
	/**
	 * 判断任务是否被中止，比如同步到一半，客户删除文件
	 * @param taskId
	 * @return
	 */
	public boolean isTaskStop(String taskId){
		FdTaskList task = (FdTaskList)hiberDao.get(FdTaskList.class, taskId);
		if(task == null)
			return true;
		if(task.getTaskStatus().equals(Constants.TASK_STATUS_STOP) 
				|| task.getTaskStatus().equals(Constants.TASK_STATUS_CANCEL))
			return true;
		return false;
	}
	
	/**
	 * 客户删除正在同步的文件，中止同步任务
	 * @param filename
	 * @return
	 */
	public int cancelTaskForDelete(String customer, String filename){
		String sql = "update FD_Task_List set taskStatus=? where entername=? and  filename=? and (taskStatus=? or taskStatus=?)";
		Object[] values = {Constants.TASK_STATUS_CANCEL, customer, filename, Constants.TASK_STATUS_WAIT, Constants.TASK_STATUS_RUN};
		return jdbcDao.update(sql, values);
	}
	
	public int cancelTaskForUpload(String customer, String filename){
		String sql = "update FD_Task_List set taskStatus=? where entername=? and  filename=? and taskStatus in(?,?,?)";
		Object[] values = {Constants.TASK_STATUS_CANCEL, customer, filename, Constants.TASK_STATUS_WAIT, Constants.TASK_STATUS_RUN,Constants.TASK_STATUS_FAILURE};
		return jdbcDao.update(sql, values);
	}
	
	public void setHiberDao(HiberDao hiberDao) {
		this.hiberDao = hiberDao;
	}
	public void setJdbcDao(JdbcDao jdbcDao) {
		this.jdbcDao = jdbcDao;
	}
	
	/**
	 * 获取上传服务器的运营商
	 * @param ip
	 * @return
	 */
	public String getUplaodServerCarryCompanyByIp(String ip){
		String sql = "select carryCompany from FD_Upload_Server where ip=?";
		Object[] values = {ip};
		Map map = jdbcDao.queryForMap(sql, values);
		if(map == null)
			return "0";
		return (String)map.get("carryCompany");
	}
	
	/**
	 * 设置机器的状态为不可用
	 * @param ip
	 */
	public void setServerUnactive(String ip){
		String sql = "update FD_Down_Server set active=? where ip=?";
		Object[] values = {Constants.SERVER_ACTIVE_FALSE, ip};
		jdbcDao.update(sql, values);
	}
	
	/**
	 * 获取备份机器
	 * @param uploadIp
	 * @return
	 */
	public Map getBakServer(String uploadIp){
		String sql="select b.serverName, b.ip, b.carryCompany, b.password, b.port from FD_Upload_Server a, FD_Upload_Server b where a.bakServer=b.serverId and a.ip=?";
		Object[] values = {uploadIp};
		return jdbcDao.queryForMap(sql, values);
	}
	
	/**
	 * 获取等待的人工任务
	 * @return
	 */
	public List getWaitManualTask(){
		
		String hql = "from FdManualTask o where taskStatus='wait' order by timestamp";
		
		return hiberDao.selectPages(hql, 0, 10);
		
	}
	/**
	 * 更新人工任务开始
	 * @param taskStatus
	 * @return
	 */
	public void updateManualTaskStart(String taskId, String taskStatus){
		String sql = "update FD_Manual_Task set taskStatus=?, syncStartTime=? where taskId=?";
		Object[] values = {taskStatus, new Timestamp(System.currentTimeMillis()), taskId};
		jdbcDao.update(sql, values);
	}
	/**
	 * 更新人工任务结束
	 * @param taskId
	 * @param taskStatus
	 */
	public void updateManualTaskEnd(String taskId, String taskStatus){
		String sql = "update FD_Manual_Task set taskStatus=?, syncEndTime=? where taskId=?";
		Object[] values = {taskStatus, new Timestamp(System.currentTimeMillis()), taskId};
		jdbcDao.update(sql, values);
	}
	
	/**
	 * 更新rename任务的状态为wait
	 * @param preTaskId
	 */
	public void updateRenameManualTaskWait(String preTaskId){
		String sql = "update FD_Manual_Task set taskStatus=? where preTask=?";
		Object[] values = {Constants.TASK_STATUS_WAIT, preTaskId};
		jdbcDao.update(sql, values);	
	}
	
	/**
	 * 获取文件的md5值
	 * @param fileId
	 * @return
	 */
	public String getFileMd5(String fileId){
		if(fileId == null)
			return null;
		String sql = "select MD5 from FD_File where fileId=?";
		Object[] values = {fileId};
		Map map = jdbcDao.queryForMap(sql, values);
		if(map != null){
			return (String)map.get("MD5");
		}else{
			return null;
		}
	}
	
	/**
	 * 获取文件的md5值
	 * @param fileId
	 * @return
	 */
	public long getFilesize(String fileId){
		if(fileId == null)
			return 0;
		String sql = "select fileSize from FD_File where fileId=?";
		Object[] values = {fileId};
		return  jdbcDao.queryForLong(sql, values);
		
	}
	
	/**
	 * 获取客户的上传服务器ip
	 * @param entername
	 * @return
	 */
	public String getUploadServerIpByEntername(String entername){
		String sql = "SELECT a.ip from FD_Upload_Server a, FD_Customer_Uploadserver b, PW_OPER c where a.serverId=b.serverId and b.customerId=c.OPER_CODE and c.OPER_CODE=?";
		Object[] values = {entername};
		List list = jdbcDao.queryForList(sql, values);
		if(list.size() == 0)
			throw new RuntimeException("请设置客户" + entername + "的上传服务器");
		Map map = (Map)list.get(0);
		return (String)map.get("ip");		
	}
	
	/**
	 * 手工同步成功后，更新任务明细
	 * @param taskId 手工任务Id
	 */
	public void updateTaskDetailSuccess(FdManualTask task){
		
		
		
		if(task == null || task.getFilename() == null)				
			return;
		
		if(task.getTaskkind().equals(Constants.TASK_KIND_UPLOAD) || task.getTaskid().equals(Constants.TASK_KIND_RENAME)){
			String sql = "update FD_Task_Detail set syncStatus=? where taskId in (select taskId from FD_Task_List where entername=? and filename = ? and taskKind=?) and ip=?";
			Object[] values = {Constants.SYNC_STATUS_HAS_SYNC, task.getEntername(), task.getFilename(), task.getTaskkind(), task.getTargetip()};
			jdbcDao.update(sql, values);
		}		
	}	
	
	/**
	 * 根据机器ip获取客户列表
	 * @param ip
	 * @return
	 */
	public List<String> getEnternamesByServerIp(String ip){
		
		List<String> result = new ArrayList<String>();
		
		if(this.isUploadServer(ip)){//上传服务器
			
			String sql = "select entername from SMM_user where userid in(select userid from user_uploadserver where serverId=? union select a.userId from user_uploadserver a, FD_Upload_Server b where a.serverId=b.serverId and b.bakServer=?)";
			String serverId = this.getUploadServerIdByIp(ip);
			Object[] values = {serverId, serverId};
			List list = jdbcDao.queryForList(sql, values);
			for(int i=0; i<list.size(); i++){
				String entername = (String)((Map)list.get(i)).get("entername");
				result.add(entername);
			}
			
		}else{//普通下载机器
			
			String sql = "select a.entername from FD_Customer a, FD_Customer_Server b, FD_Down_Server c where a.customerId=b.customerId and b.serverId=c.serverId and c.ip=?";
			Object[] values = {ip};
			List list = jdbcDao.queryForList(sql, values);
			if(list.size() != 0){
				StringBuffer sb = new StringBuffer("select wsfdAccount from FD_Account_Map where cdnAccount in('");
				for(int i=0; i<list.size(); i++){
					String entername = (String)((Map)list.get(i)).get("entername");
					result.add(entername);
					if(i!=0)
						sb.append(",' ");
					sb.append(entername);
					sb.append("'");
				}
				sb.append(")");
				list = jdbcDao.queryForList(sb.toString());
				for(int i=0; i<list.size(); i++){
					String entername = (String)((Map)list.get(i)).get("wsfdAccount");
					result.add(entername);
				}
			}
		}
		
		
		return result;
		
	}
	
	/**
	 * 判断是否为上传服务器
	 * @param ip
	 * @return
	 */
	public boolean isUploadServer(String ip){
		String sql = "select ip from FD_Upload_Server where ip=?";
		Object[] values = {ip};
		Map map = jdbcDao.queryForMap(sql, values);
		if(map == null)
			return false;
		return true;
	}
	
	public boolean canStartSyncDirTask(String sourceIp){
		String sql = "select distinct sourceIp from FD_Manual_Task where sourceIp=? and taskKind=? and taskStatus=?";
		Object[] values = {sourceIp, Constants.TASK_KIND_SYNCCUSTOMNER, Constants.TASK_STATUS_RUN};
		List list = jdbcDao.queryForList(sql, values);
		if(list.size() != 0)
			return false;
		return true;
		
	}
	
	public boolean canStartSyncManualUpload(String sourceIp){
		String sql = "select distinct sourceIp from FD_Manual_Task where sourceIp=? and taskKind in(?,?) and taskStatus=?";
		Object[] values = {sourceIp, Constants.TASK_KIND_SYNCCUSTOMNER, Constants.TASK_KIND_UPLOAD, Constants.TASK_STATUS_RUN};
		List list = jdbcDao.queryForList(sql, values);
		if(list.size() != 0)
			return false;
		return true;
		
	}
	
	/**
	 * 更新同步机器任务的任务状态
	 * @param taskId
	 */
	public void updateParentTaskStatus(FdManualTask task){
		
		String taskId = task.getParenttask();
		if(taskId == null)
			return;
		
		String sql = "select distinct sourceIp from FD_Manual_Task where parentTask=? and taskStatus in (?, ?)";
		Object[] values = {taskId, Constants.TASK_STATUS_RUN, Constants.TASK_STATUS_WAIT};
		List list = jdbcDao.queryForList(sql, values);
		
		if(list.size() != 0)//还存在未完成的任务
			return;
		values = new Object[]{taskId, Constants.TASK_STATUS_STOP, Constants.TASK_STATUS_FAILURE};
		list = jdbcDao.queryForList(sql, values);
		
		if(list.size() != 0)
			this.updateManualTaskEnd(taskId, Constants.TASK_STATUS_FAILURE);
		else
			this.updateManualTaskEnd(taskId, Constants.TASK_STATUS_SUCCESS);
	}
	
	/**
	 * 根据ip获取上传服务器id
	 * @param ip
	 * @return
	 */
	public String getUploadServerIdByIp(String ip){
		String sql = "select serverId from FD_Upload_Server where ip = ?";
		Object[] values = {ip};
		Map map = jdbcDao.queryForMap(sql, values);
		if(map != null){
			return (String)map.get("serverId");
		}else{
			throw new RuntimeException("上传服务器不存在，ip="+ip);
		}
	}
	
	public List getReportTask(){		
		
		String hql="from FdTaskList where ((taskStatus='success' and isReport!='S') or (taskStatus='failure' and isReport='N')) and reportId IS NOT NULL and reportType != '0'";		
		
		return hiberDao.selectPages(hql, 0, 30);
	}
	
	public List getPurgeTask(){
		String hql = "from FdTaskList where isPurge = 'Y' and taskStatus='success' order by timestamp";
		return hiberDao.selectPages(hql, 0, 30);
//		String sql = "select * from FD_Task_List where isPurge = 'Y' and taskStatus='success' order by timestamp";
//		return jdbcDao.queryForList(sql);
	}
	
	public void updateReportStatus(String taskId, String status){
		String sql = "update FD_Task_List set isReport = ? where taskId = ?";
		Object[] values = {status, taskId};
		jdbcDao.update(sql, values);
	}
	
	public void updatePurgeStatus(String taskId, String status){
		String sql = "update FD_Task_List set isPurge = ? where taskId = ?";
		Object[] values = {status, taskId};
		jdbcDao.update(sql, values);
	}
	
	/***
	 * 获取失败的机器数
	 * @param taskId
	 * @return
	 */
	public long getFaiServerCount(String taskId){
		String sql = "select count(*) from FD_Task_Detail where taskId=? and syncStatus!=?";
		Object[] values = {taskId, Constants.SYNC_STATUS_HAS_SYNC};
		return jdbcDao.queryForLong(sql, values);
	}
	
	public long getUploadFailureCount(){
		String sql = "select count(*) from FD_Task_List where taskStatus=? and taskKind=?";
		Object[] values = {Constants.TASK_STATUS_FAILURE, Constants.TASK_KIND_UPLOAD};
		return jdbcDao.queryForLong(sql, values);
	}
	
	public long getUploadSuccessCount(){
		String sql = "select count(*) from FD_Task_List where taskStatus=? and taskKind=?";
		Object[] values = {Constants.TASK_STATUS_SUCCESS, Constants.TASK_KIND_UPLOAD};
		return jdbcDao.queryForLong(sql, values);
	}
	
	public long getUploadReportSuccessCount(){
		String sql = "select count(*) from FD_Task_List where taskKind=? and isReport=?";
		Object[] values = {Constants.TASK_KIND_UPLOAD, Constants.IS_REPORT_S};
		return jdbcDao.queryForLong(sql, values);
	}
	
	public long getUploadCount(){
		String sql = "select count(*) from FD_Task_List where taskKind=?";
		Object[] values = {Constants.TASK_KIND_UPLOAD};
		return jdbcDao.queryForLong(sql, values);
	}
	
	public long getCheckCustomerRunCount(){
		String sql = "select count(*) from FD_Manual_Task where taskKind=? and taskStatus=?";
		Object[] values = {Constants.TASK_KIND_CHECKCUSTOMER, Constants.TASK_STATUS_FAILURE};
		return jdbcDao.queryForLong(sql,values);
	}
	
	
	
	/**
	 * 任务发起后更新机器的同步状态为开始同步
	 * @param taskId
	 */
	public void updateAllServerSyncStart(String taskId){
		String sql = "update FD_Task_Detail set syncStatus=?, syncStartTime = now() where taskId = ?";
		Object[] values = {Constants.SYNC_STATUS_CUR_SYNC, taskId};
		jdbcDao.update(sql, values);
	}
	
//	public void updateUserServer(){
//		String hql = "from SmmUser";
//		List<SmmUser> list = hiberDao.find(hql);
//		for(int i=0; i<list.size(); i++){
//			UserUploadserver server = new UserUploadserver();
//			server.setUserid(list.get(i).getUserid());
//			server.setServerid("uploadServer54");
//			hiberDao.save(server);
//		}
//	}
	
	/**
	 * 同机房用scp，否则用wsftp
	 */
	public String getProtocol(String sourceIp, String targetIp){
		String sql = "select distinct nodeId from FD_Down_Server where ip=? or ip=?";
		Object[] values = {sourceIp, targetIp};
		List list = jdbcDao.queryForList(sql, values);
		if(list.size() == 2)
			return Constants.PROTOCOL_WS;
		else
			return Constants.PROTOCOL_SCP;
			
	}
	
	/**
	 * 获取用户的上传服务器
	 * @param entername
	 * @return
	 */
	public Map getSourceInfoByCustomer(String entername){
		String sql = "select us.ip, pw.OPER_PWD as password from FD_Upload_Server us, FD_Customer_Uploadserver fcu,PW_OPER pw where us.serverId = fcu.serverId and us.uploadType=? and fcu.customerId=pw.OPER_CODE and pw.OPER_CODE = ?";
		Object[] values = {"ftp", entername};
		List<Map> list = jdbcDao.queryForList(sql, values);
		if(null==list||list.isEmpty()) return new HashMap();
		return list.get(0);
	}
	

	
	/**
	 * 当upload任务出现异常时，同时更新rename任务为stop
	 * @param taskId
	 */
	public void updatePreTaskStop(String taskId){
		String sql = "update FD_Task_List set taskStatus = ? where preTask = ?";
		Object[] values = {Constants.TASK_STATUS_STOP, taskId};
		jdbcDao.update(sql, values);
	}
	
	/**
	 * 根据客户获取purge的域名
	 * @param customer
	 * @return
	 */
	public List<Map> getPurgeDomain(String customer){
		String sql = "select url, dir from FD_Purge where customer = ?";
		Object[] values = {customer};
		return jdbcDao.queryForList(sql, values);
	}
	
	/**
	 * 根据type从参数表获取客户名称
	 * @param type
	 * @return
	 */
	public String getCustomerbyType(String type){
		String sql = "select displayValue from COM_Param where paramType='customerType' and paramValue=?";
		Object[] values = {type};
		Map map = jdbcDao.queryForMap(sql, values);
		if(map == null) return "";
		return (String)map.get("displayValue");
	}
	
	/**
	 * 根据customer得到客户配置
	 * @param customer
	 * @return Map
	 */
	public Map getCustomerConf(String customer){
		String sql = "select * from FD_Customer_Config where customer=?";
		Object[] values = {customer};
		
		return jdbcDao.queryForMap(sql, values);
	}
	
	/**
	 * 根据customer从参数表中获取客户type
	 * @param customer
	 * @return
	 */
	public String getTypebyCustomer(String customer){
		String sql = "select paramValue from COM_Param where paramType='customerType' and displayValue=?";
		Object[] values = {customer};
		Map map = jdbcDao.queryForMap(sql, values);
		if(map == null) return "";
		return (String)map.get("paramValue");
	}
	
	public Integer getAllowFailureCount(String customer){
		String sql = "select allowFailureCount from FD_Customer_Config where customer=?";
		Object[] values = {customer};
		Map map = jdbcDao.queryForMap(sql, values);
		if(map == null) return new Integer(0);
		return  (Integer)map.get("allowFailureCount");
	}
	
	/**
	 * 系统启动的时候清理run的任务，将其状态置为wait
	 */
	public void clearRunTask(){
		
		jdbcDao.execute("delete a from FD_Task_Detail a, FD_Task_List b where a.taskId=b.taskId and b.taskStatus='run'");
	
		jdbcDao.execute("update FD_Task_List set taskStatus='wait' where taskStatus='run'");
	}
	
	/**
	 * 查询汇报邮件需要的信息
	 * @return
	 */
	public List getCustomerFailureCount(){
		String sql = "select entername, count(*) as falCount from FD_Task_List where taskStatus in('stop','failure') group by entername order by entername";
		return jdbcDao.queryForList(sql);
	}
	
	/**
	 * 获取客户当天正在同步或已经同步的任务数
	 * @param customername
	 * @return
	 */
	public long getCustomerDaySyncCount(String customername){
		String sql = "select count(*) as taskCount from FD_Task_List where entername=? and syncStartTime>? and taskKind=? and taskStatus!=?";
		Object[] values = {customername, new java.sql.Date(System.currentTimeMillis()), Constants.TASK_KIND_UPLOAD, Constants.TASK_STATUS_WAIT};
		return jdbcDao.queryForLong(sql, values);
	}
	
	/**
	 * 获取需要监控文件完整性的任务
	 * @return
	 */
	public List<Map> getCheckTasks(){
		//String sql = "select customer, checkInterval, checkOvertime from FD_Customer_Config where checkInterval > '0'";
		
		//对不在配置表中的客户也做校验，同时过滤掉配置表中存在但用户表中不存在的配置
		StringBuffer sb = new StringBuffer("select customer, checkInterval, checkOvertime from FD_Customer_Config a, PW_OPER b");
		sb.append(" where a.customer=b.OPER_CODE and checkInterval > '0'");
		sb.append(" union");
		sb.append(" select OPER_CODE as customer, 60 as checkInterval, 10 as checkOvertime from PW_OPER");
		sb.append(" where OPER_CODE NOT IN (select customer from FD_Customer_Config)");
		sb.append(" and OPER_CODE NOT IN ('admin','wsfdtest','test')");
		
		return jdbcDao.queryForList(sb.toString());
	}
	
	public boolean hasUnsyncTask(String customer){
		
		String sql = "select count(*) from FD_Task_List where taskStatus in (?,?,?) and entername=?";
		
		Object[] values = {Constants.TASK_STATUS_RUN, Constants.TASK_STATUS_WAIT, Constants.TASK_STATUS_FAILURE, customer};
		long count = jdbcDao.queryForLong(sql, values);
		
		if(count > 0)
			return true;
		else
			return false;
	}
	
	
	
	//**********************************LW-FD界面*************************************//	
	/**
	 * 获得所有的wsFD登陆客户(本地客户)
	 */
    	public List getWsfdAccount(){
    	    String sql = "SELECT OPER_CODE AS wsfdAccount FROM PW_OPER WHERE OPER_TYPE <> 1 order by OPER_CODE asc";
    	    return jdbcDao.queryForList(sql);
    	}
    	/**
	 * 获得所有的CDN客户
	 */
    	public List getCdnAccount(){
    	    String sql = "SELECT entername AS cdnAccount FROM FD_Customer order by entername asc";
    	    return jdbcDao.queryForList(sql);
    	}
    	
    	
    	/**
    	 * 获得所有的源服务器 包含serverId
    	 * @return
    	 */
    	public List getMapUploadServer(){
    	    String sql = "SELECT serverId,ip,uploadType,bakServer FROM FD_Upload_Server";
    	    return jdbcDao.queryForList(sql);
    	}
	    
    	/**
    	 * 查询下载服务器信息
    	 * @param hs
    	 * @return
    	 */
	    public void getServerInfo(Map hs,PageInfo page){
		List<Object> params = new ArrayList<Object>();		
		StringBuffer sql;
		Object customer = hs.get("customerName");
		if(customer!=null&&StringUtils.isNotBlank(String.valueOf(customer))){
			String customerName = this.getMapEntername(customer.toString());
			sql = new StringBuffer("select b.entername,a.serverIp, a.sshUser, a.sshPwd,a.sshPort,a.isp, a.serverName from FD_Source_Server a, FD_Customer b where a.groupId=b.sourceGroup ");
			sql.append(" AND b.entername=?   ");
		    params.add(customerName);
		}else {
			sql=new StringBuffer("select a.serverIp, a.sshUser, a.sshPwd,a.sshPort,a.isp, a.serverName from FD_Source_Server a where 1=1");
		}
		Object isp = hs.get("isp");
		if(isp!=null&&StringUtils.isNotBlank(String.valueOf(isp))){
		    sql.append(" AND a.isp = ? ");
		    params.add(isp);
		}
		Object ip = hs.get("serverIp");
		if(ip!=null&&StringUtils.isNotBlank(String.valueOf(ip))){
		    sql.append(" AND a.serverIp LIKE ? ");
		    params.add("%"+ip+"%");
		}
		sql.append(" ORDER BY 1");	
//		log.logDebug("ServerInfo SQL:" + sql.toString());
		QuerySql qs = new QuerySql(sql);
		qs.setValues(params);
		jdbcDao.queryForPage(page, qs);		
	    }
	    
	    /**
	     * 查询同步文件任务信息
	     * @param hs
	     * @retur:n
	     */
	    public void getSyncFileInfo(Map hs,PageInfo page){
		List<Object> params = new ArrayList<Object>();
		StringBuffer sql = new StringBuffer("SELECT t.taskId,t.sourceIp,t.entername,t.filename,t.newName,t.compress,t.timestamp,t.taskStatus,t.taskKind,t.syncStartTime,t.syncEndTime ");
		// sql.append(" (SELECT COUNT(*) FROM FD_Task_Detail d WHERE t.taskId = d.taskId AND d.syncStatus = 'hasSync')/(select count(*) from FD_Task_Detail d where t.taskId = d.taskId)*100 AS progress");
		sql.append(" FROM FD_Task_List t  ");
		Object realName = hs.get("realName");
        if(realName!=null&&StringUtils.isNotBlank(String.valueOf(realName))){
            sql.append(" left join PW_OPER p on t.entername=p.OPER_CODE where p.OPER_NAME like ? ");
            params.add("%" + String.valueOf(realName) + "%");
        }
        else{
            sql.append(" where 1=1 ");
        }
        
        Object allQueryOpers = hs.get("allQueryOpers");
        // 判断是否查询全部的可查询客户列表
        if(allQueryOpers != null && "1".equals(String.valueOf(allQueryOpers))){
            List<String> customerNameList = (List<String>)hs.get("customerNameList");
            if(customerNameList != null && !customerNameList.isEmpty()){
                sql.append(" AND t.entername in(" + StringUtil.listToDbString(customerNameList) + ")");
            }
        }
        else{
            // 查询单个客户
            Object customerName = hs.get("customerName");
            if(customerName!=null&&StringUtils.isNotBlank(String.valueOf(customerName))){
                sql.append(" AND t.entername = ? ");
                params.add(customerName);
            } 
        }
        
		Object fileName = hs.get("fileName");
		if(null!=fileName&&StringUtils.isNotBlank(String.valueOf(fileName))){
		    sql.append(" AND t.filename LIKE ? ");
		    params.add("%"+fileName+"%");
		}
		Object taskType = hs.get("taskType");
		if(null!=taskType&&StringUtils.isNotBlank(String.valueOf(taskType))){
		    sql.append(" AND t.taskKind = ? ");
		    params.add(taskType);
		}
		Object status = hs.get("status");
		if(null!=status&&StringUtils.isNotBlank(String.valueOf(status))){
		    sql.append(" AND t.taskStatus = ? ");
		    params.add(status);
		}
		Object sourceIp = hs.get("sourceIp");
		if(null!=sourceIp&&StringUtils.isNotBlank(String.valueOf(sourceIp))){
		    sql.append(" AND t.sourceIp LIKE ? ");
		    params.add("%"+sourceIp+"%");
		}
		String startDate = (String)hs.get("startDate");
		String endDate = (String) hs.get("endDate");
		if ((null != startDate&&StringUtils.isNotBlank(String.valueOf(startDate)))&& (null == endDate||"".equals(endDate))) {
			startDate+=" 00:00:00";
			String aux = startDate.replaceAll("-|:| ", "");
			Long timeStamp = new Long(aux);
			sql.append(" AND t.timestamp >= ? ");
			params.add(timeStamp);
		} else if ((null == startDate||"".equals(startDate) )&&( null != endDate&&StringUtils.isNotBlank(String.valueOf(endDate)))) {
			endDate+=" 24:00:00";
			String aux = endDate.replaceAll("-|:| ", "");
			Long timeStamp = new Long(aux);
			sql.append(" AND t.timestamp <= ? ");
			params.add(timeStamp);
		} else if ((null != startDate &&StringUtils.isNotBlank(String.valueOf(startDate)))&& (null != endDate&&StringUtils.isNotBlank(String.valueOf(endDate)))) {
			startDate+=" 00:00:00";
			endDate+=" 24:00:00";
			String aux = startDate.replaceAll("-|:| ", "");
			String aux2 = endDate.replaceAll("-|:| ", "");
			Long timeStamp = new Long(aux);
			Long timeStamp2 = new Long(aux2);
			sql.append(" AND t.timestamp between ? and ?");
			params.add(timeStamp);
			params.add(timeStamp2);
		}
		sql.append(" ORDER BY t.timestamp DESC ");
		//log.logInfo("SyncFileInfo SQL:" + sql.toString());
		QuerySql qs = new QuerySql(sql);
		qs.setValues(params);
		jdbcDao.queryForPage(page, qs);	
	    }
	    
	    public Map getTaskProgress(String taskId){
		String sql = "SELECT (SELECT COUNT(syncStatus) FROM FD_Task_Detail a WHERE a.taskId = ? AND a.syncStatus = 'hasSync')/(select COUNT(syncStatus) from FD_Task_Detail b where  b.taskId = ? )*100 AS progress";
		List<String> params = new ArrayList<String>();
		params.add(taskId);
		params.add(taskId);		
		return jdbcDao.queryForMap(sql,params.toArray());
	    }
	    
	 
	    
	    
	    
	    
	    /**
	     * 删除同步文件任务
	     * @param taskIds
	     */
	    public void deleteSyncFileInfo(String[] taskIds){
		
		StringBuffer sql_detail = new StringBuffer("DELETE FROM FD_Task_Detail WHERE 1<>1 ");
		for(String id:taskIds){
		    sql_detail.append(" OR taskId = '" + id +"'");
		}
		jdbcDao.execute(sql_detail.toString());
		
		StringBuffer sql = new StringBuffer("DELETE FROM FD_Task_List WHERE 1<>1 ");
		for(String id:taskIds){
		    sql.append(" OR taskId = '" + id +"'");
		}			
		jdbcDao.execute(sql.toString());
	    }
	    
	    /**
	     * 修改同步完成状态
	     * @param taskIds
	     */
	    public void updateSyncFileInfo(String[] taskIds){
		List<String> sqls = new ArrayList<String>();
		StringBuffer sql_detail = new StringBuffer("UPDATE FD_Task_Detail SET syncStatus ='hasSync' WHERE 1<>1 ");
		for(String id:taskIds){
		    sql_detail.append(" OR taskId = '" + id +"'");
		}
		sqls.add(sql_detail.toString());
		StringBuffer sql = new StringBuffer("UPDATE FD_Task_List SET taskStatus='success' WHERE 1<>1 ");
		for(String id:taskIds){
		    sql.append(" OR taskId = '" + id +"'");
		}
		sqls.add(sql.toString());
		//log.logInfo("DELETE SyncFileInfo SQL:" + sql.toString());		
		jdbcDao.batchUpdate(sqls);
	    }
	    
	    /**
	     * 重新启动任务
	     * @param taskIds
	     */
//	    public void restartSyncTask(String[] taskIds){
//		List<String> sqls = new ArrayList<String>();
//		if(null==taskIds || 0==taskIds.length)
//			return ;
//		StringBuffer sql_detail = new StringBuffer("delete from FD_Task_Detail WHERE 1<>1 ");
//		for(String id:taskIds){
//		    sql_detail.append(" OR taskId = '" + id +"'");
//		}
//		sqls.add(sql_detail.toString());
//		StringBuffer sql = new StringBuffer("UPDATE FD_Task_List SET taskStatus='wait' WHERE 1=1 and taskKind in ('upload','delete','rename','mkdir') and taskStatus in ('stop','failure','success','cancel') and taskId in (");
//		for(String id:taskIds){
//		    sql.append("'" + id +"',");
//		}
//		sql.deleteCharAt(sql.length()-1);
//		sql.replace(sql.length()-1, sql.length(), ")");
//		sqls.add(sql.toString());
//		log.logInfo("Restart task SQL:" + sql.toString());		
//		jdbcDao.batchUpdate(sqls);
//	    }
	    
	    /**
	     * 获得同步任务明细
	     * @param taskId
	     * @param hs
	     * @param page
	     */
	    public void getSyncFileDetail(String taskId,Map hs,PageInfo page){
		List<Object> params = new ArrayList<Object>();
		StringBuffer sql = new StringBuffer("");
		sql.append("SELECT id, serverName,ip,sourceIp,syncStatus,syncStartTime,syncEndTime,comment FROM FD_Task_Detail a left join FD_Errorno b on a.errorno=b.errorno  WHERE 1=1 AND taskId = '"+taskId+"' ");
		Object serverName = hs.get("serverName");
		if(serverName!=null&&StringUtils.isNotBlank(String.valueOf(serverName))){
		    sql.append(" AND serverName LIKE ? ");
		    params.add("%"+serverName+"%");
		}
		Object ip = hs.get("ip");
		if(ip!=null&&StringUtils.isNotBlank(String.valueOf(ip))){
		    sql.append(" AND ip LIKE ? ");
		    params.add("%"+ip+"%");
		}
		Object syncStatus = hs.get("syncStatus");
		if(syncStatus!=null&&StringUtils.isNotBlank(String.valueOf(syncStatus))){
		    sql.append(" AND syncStatus = ? ");
		    params.add(syncStatus);
		}	
		sql.append(" ORDER BY 1 ");
		QuerySql qs = new QuerySql(sql);
		qs.setValues(params);
		jdbcDao.queryForPage(page, qs);		
	    }
	
	
	    /**
	     * 删除同步任务明细
	     * @param taskIds
	     */
	    public void deleteSyncFileDetail(String[] taskIds){
		StringBuffer sql = new StringBuffer("DELETE FROM FD_Task_Detail WHERE 1<>1 ");
		for(String id:taskIds){
		    sql.append(" OR id = '" + id +"'");
		}
		//log.logInfo("DELETE SyncFileInfo SQL:" + sql.toString());
		jdbcDao.execute(sql.toString());
	    }
	
	    /**
	     * 修改同步任务明细
	     * @param taskIds
	     */
	    public void updateSyncFileDetail(String[] taskIds){
		StringBuffer sql = new StringBuffer("UPDATE FD_Task_Detail SET syncStatus='hasSync' WHERE 1<>1 ");
		for(String id:taskIds){
		    sql.append(" OR id = '" + id +"'");
		}
		//log.logInfo("DELETE SyncFileInfo SQL:" + sql.toString());
		jdbcDao.execute(sql.toString());
	    }
	
	    /**
	     * 文件查询
	     * @param hs
	     * @param page
	     */
	    public void getFileDetail(Map hs,PageInfo page){
		List<Object> params = new ArrayList<Object>();
		StringBuffer sql = new StringBuffer("");
		sql.append("SELECT * FROM FD_File  WHERE 1=1 ");
		Object allQueryOpers = hs.get("allQueryOpers");
        // 判断是否查询全部的可查询客户列表
        if(allQueryOpers != null && "1".equals(String.valueOf(allQueryOpers))){
            List<String> customerNameList = (List<String>)hs.get("customerNameList");
            if(customerNameList != null && !customerNameList.isEmpty()){
                sql.append(" AND entername in(" + StringUtil.listToDbString(customerNameList) + ")");
            }
        }
        else{
            Object customerName = hs.get("customerName");
            if(customerName!=null&&StringUtils.isNotBlank(String.valueOf(customerName))){
                sql.append(" AND entername = ? ");
                params.add(customerName);
            } 
        }
		
		Object fileName = hs.get("fileName");
		if(fileName!=null&&StringUtils.isNotBlank(String.valueOf(fileName))){
		    sql.append(" AND filename LIKE ? ");
		    params.add("%"+fileName+"%");
		}
		Object startTime = hs.get("startTime");
		if(startTime!=null&&StringUtils.isNotBlank(String.valueOf(startTime))){
		    sql.append(" AND uploadTime >= '"+ startTime+"'");
		    //params.add("'"+startTime+"'");
		}
		Object endTime = hs.get("endTime");
		if(endTime!=null&&StringUtils.isNotBlank(String.valueOf(endTime))){
		    sql.append(" AND uploadTime <= '"+ endTime+"'");
		   // params.add("'"+endTime+"'");
		}
		
		sql.append(" ORDER BY uploadTime desc ");
		//log.logInfo("File Detail SQL:"+sql.toString());
		QuerySql qs = new QuerySql(sql);
		qs.setValues(params);
		jdbcDao.queryForPage(page, qs);
	    }
	    
	    
	    /**
	     * 源服务器查询
	     * @param hs
	     * @param page
	     */
	    public void getUploadServer(Map hs,PageInfo page){
		List<Object> params = new ArrayList<Object>();
		StringBuffer sql = new StringBuffer("");
		sql.append("SELECT s.serverId,s.serverName,s.carryCompany,s.ip,s.password,s.uploadType,s.port,(SELECT x.ip FROM FD_Upload_Server x where s.bakServer=x.serverId) as bakServer FROM FD_Upload_Server s  WHERE 1=1 ");
		Object upServerName = hs.get("upServerName");
		if(upServerName!=null&&StringUtils.isNotBlank(String.valueOf(upServerName))){
		    sql.append(" AND s.serverName = ? ");
		    params.add("%"+upServerName+"%");
		}
		Object ip = hs.get("ip");
		if(ip!=null&&StringUtils.isNotBlank(String.valueOf(ip))){
		    sql.append(" AND s.ip LIKE ? ");
		    params.add("%"+ip+"%");
		}
		Object isp = hs.get("isp");
		if(isp!=null&&StringUtils.isNotBlank(String.valueOf(isp))){
		    sql.append(" AND s.carryCompany = ? ");
		    params.add(isp);
		}		
		sql.append(" ORDER BY s.serverName ASC ");
		//log.logInfo("UploadServer SQL:"+sql.toString());
		QuerySql qs = new QuerySql(sql);
		qs.setValues(params);
		jdbcDao.queryForPage(page, qs);
	    }	
	    
	    /**
	     * 获得备份服务器
	     * @return
	     */
	    public List getBakServer(){
		String sql = "SELECT serverId,ip FROM FD_Upload_Server";
		return jdbcDao.queryForList(sql);
	    }
	   
	    /**
	     * 确认服务器是否备份服务器 ,用于删除服务器时的判断
	     * @param serverId
	     * @return
	     */
	    public boolean serverIsBak(String serverId){		
		String sql = "SELECT bakServer FROM FD_Upload_Server WHERE bakServer = '" +serverId+ "'";
		List list = jdbcDao.queryForList(sql);
		if(list!=null&&!list.isEmpty()){
		    return false;
		}
		return true;
	    }
	    
	    /**
	     * 获得已经存在的所有IP
	     * @return
	     */
	    public boolean checkIpExist(String ip){		
		String sql = "SELECT * FROM FD_Upload_Server where ip = '"+ip+"'";
		List list = jdbcDao.queryForList(sql);
		if(null==list||list.isEmpty()) return false; //not exist
		return true; //exist
	    }
	    
	    /**
	     * 客户映射关系查询
	     * @param hs
	     * @param page
	     */
	    public void getCustomer(Map hs,PageInfo page){
		List<Object> params = new ArrayList<Object>();
		StringBuffer sql = new StringBuffer("");
		sql.append("SELECT id,wsfdAccount,cdnAccount FROM FD_Account_Map WHERE 1=1 ");
		Object cdnName = hs.get("cdnName");
		if(cdnName!=null&&StringUtils.isNotBlank(String.valueOf(cdnName))){
		    sql.append(" AND cdnAccount = ? ");
		    params.add(cdnName);
		}
		Object localName = hs.get("localName");
		if(cdnName!=null&&StringUtils.isNotBlank(String.valueOf(localName))){
		    sql.append(" AND wsfdAccount = ? ");
		    params.add(localName);
		}		
		sql.append(" ORDER BY wsfdAccount ASC ");
		//log.logInfo("UploadServer SQL:"+sql.toString());
		QuerySql qs = new QuerySql(sql);
		qs.setValues(params);
		jdbcDao.queryForPage(page, qs);
	    }
	
	    /**
	     * 获得已经取得了映射关系的OPER_CODE
	     * @return
	     */
	    public List getExistOper(){		
		String sql = "SELECT distinct(wsfdAccount) FROM FD_Account_Map";		 
		return jdbcDao.queryForList(sql);
	    }
	
	    /**
	     * 依条件查询客户源服务器
	     * @param hs
	     * @return
	     */
	    public void getUserServer(Map hs,PageInfo page){
		List<Object> params = new ArrayList<Object>();
		StringBuffer sql = new StringBuffer("");
		sql.append("SELECT u.customerId,s.ip,(SELECT x.ip FROM FD_Upload_Server x where s.bakServer=x.serverId) as bakServer,s.uploadType,u.id FROM FD_Customer_Uploadserver u,FD_Upload_Server s ");
		sql.append(" WHERE 1=1 AND u.serverId = s.serverId ");
		Object customerName = hs.get("customerName");
		if(customerName!=null&&StringUtils.isNotBlank(String.valueOf(customerName))){
		    sql.append(" AND u.customerId = ? ");
		    params.add(customerName);
		}
		Object serverIp = hs.get("serverIp");
		if(serverIp!=null&&StringUtils.isNotBlank(String.valueOf(serverIp))){
		    sql.append(" AND s.ip LIKE ? ");
		    params.add("%"+serverIp+"%");
		}
		Object uploadType = hs.get("uploadType");
		if(uploadType!=null&&StringUtils.isNotBlank(String.valueOf(uploadType))){
		    sql.append(" AND s.uploadType = ? ");
		    params.add(uploadType);
		}		
		sql.append(" ORDER BY 1 ASC ");
		//log.logInfo("UploadServer SQL:"+sql.toString());
		QuerySql qs = new QuerySql(sql);
		qs.setValues(params);
		jdbcDao.queryForPage(page, qs);		
	    }
	    
	    /**
	     *获取SSH 连接条件
	     * @param wsfdAccount
	     * @param serverId
	     * @return
	     */
	    public Map getSshLoginInfo(String wsfdAccount ,String serverId){
		String sql = "SELECT pw.OPER_CODE AS user,s.password,s.ip AS host,s.port FROM PW_OPER pw,FD_Upload_Server s,FD_Customer_Uploadserver cu WHERE pw.OPER_CODE=cu.CustomerId AND cu.serverId=s.serverId and cu.CustomerId=? and cu.serverId=?";
		List result = jdbcDao.queryForList(sql, new String[]{wsfdAccount,serverId});
		if(null==result||result.isEmpty()) return null;
		return (Map)result.get(0);
	    }
	    
	    public Map getSshLoginInfo(String serverIp){
		String sql = "SELECT s.password,s.ip AS host,s.port FROM FD_Upload_Server s WHERE s.serverId = ?";
		List result = jdbcDao.queryForList(sql, new String[]{serverIp});
		if(null==result||result.isEmpty()) return null;
		return (Map)result.get(0);
	    }
	    
	    /**
	     * cancel任务
	     * @param entername
	     * @param filename
	     * @return
	     */
	    public int cancelUploadTaskforRename(String entername, String filename){
	    	String sql = "update FD_Task_List set taskStatus=? where entername=? and filename=? and taskStatus in (?,?) and taskKind in(?,?,?)";
	    	Object[] values = {Constants.TASK_STATUS_CANCEL, entername, filename, 
	    			Constants.TASK_STATUS_WAIT, Constants.TASK_STATUS_RUN,
	    			Constants.TASK_KIND_MD5SUM, Constants.TASK_KIND_DECOMPRESS, Constants.TASK_KIND_UPLOAD};
	    	return jdbcDao.update(sql, values);
	    }
	    
	    public Map getCancelUploadTask(String entername, String filename){
	    	String sql = "select * from FD_Task_List where entername=? and filename=? and taskKind=? and taskStatus=? order by timestamp desc";
	    	Object[] values = {entername, filename, Constants.TASK_KIND_UPLOAD, Constants.TASK_STATUS_CANCEL};
	    	List list = jdbcDao.queryForList(sql, values);
	    	return (Map)list.get(0);
	    }
	    
	    /**
	     * 机器文件快速同步列表
	     * @param hs
	     * @param page
	     */
	    public void getQuickFileSyncInfo(Map hs,PageInfo page){		
		StringBuffer sql = new StringBuffer("select A.taskId,A.serverIp,A.serverName,A.taskStatus,A.totalTaskCount,A.finishTaskCount,A.createTime,A.updateTime,B.comment from FD_Sync_Server_Task A left join FD_Errorno B on A.errorno = B.errorno where 1=1 ");
		QuerySql qs = new QuerySql(sql);
		Object serverIp = hs.get("serverIp");
		if(serverIp!=null&&!serverIp.equals("")) qs.appendCondition("A.serverIp", "like", "%"+serverIp+"%");
		qs.appendCondition("A.serverName", "=", hs.get("serverName"));
		qs.appendCondition("A.taskStatus", "=", hs.get("taskStatus"));		
		qs.appendString(" order by A.createTime desc ");	
		//log.logDebug("QuickFileSync SQL:" + qs.getSql());
		jdbcDao.queryForPage(page, qs);
	    } 
	    
	    
	    /**	     
	     * 如果存在相同serverIp处于wait和run状态的任务则不允许创建。
    		只能对FD_Down_Server中dataFull为1的机器创建数据同步任务。
	     * @return
	     */
	    public List getServerIpByCondition(){
		
		StringBuffer sql = new StringBuffer();
		sql.append("select serverIp ,serverName, isp from FD_Source_Server where dataFull = 1");
		sql.append(" and serverIp not in (select serverIp from FD_Sync_Server_Task where taskStatus in (?,?,?,?))");
		return jdbcDao.queryForList(sql.toString(),new String[]{Constants.TASK_STATUS_RUN,Constants.TASK_STATUS_WAIT,Constants.TASK_STATUS_TOCANCEL,Constants.TASK_STATUS_CURCANCEL});		
	    }
	    
	    /**
	     * 新增快速文件同步任务
	     * @param syncServers
	     * @param appSrvs
	     */
	    public void addQuickFileSyncTask(String[] syncServers,String[] serverNames){
		
		List<String> list = new ArrayList<String>();
		for(int i=0;i<syncServers.length;i++){
		    String sql = "insert into FD_Sync_Server_Task(taskId,serverIp,serverName,taskStatus,createTime) values('"+UuidGenerator.getUuid()+"','"+syncServers[i]+"','"+serverNames[i]+"','"+Constants.TASK_STATUS_WAIT+"',NOW())";
		    //log.logDebug("ADD QuickFileSyncTask SQL:" + sql);
		    list.add(sql);
		}
		jdbcDao.batchUpdate(list);		
	    }
	    
	    /**
	     * 修改快速文件同步任务
	     * @param taskIds
	     */
	    public void cancelQuickFileSyncTask(String[] taskIds){
		List<String> list = new ArrayList<String>();
		for(String taskId:taskIds){
		    String sql = "update FD_Sync_Server_Task set taskStatus='"
		    	+Constants.TASK_STATUS_TOCANCEL+"' where taskId = '"
		    	+taskId+"' and taskStatus in('"
		    	+Constants.TASK_STATUS_WAIT+"','" + Constants.TASK_STATUS_RUN+
		    			"')";
		    
		    list.add(sql);
		}
		jdbcDao.batchUpdate(list);		
	    }
	    
	  
	    /**
	     * 根据任务状态获取同步机器任务
	     * @param taskStatus
	     * @return
	     */
	    public List<Map> getSyncServerTasks(String taskStatus){
	    	String sql = "select taskId, serverIp from FD_Sync_Server_Task where taskStatus=?";
	    	Object[] values = {taskStatus};
	    	return jdbcDao.queryForList(sql, values);
	    }
	    
	    /**
	     * 更新syncServer任务状态
	     * @param taskId
	     * @param taskStatus
	     */
	    public void updateSyncServerTaskStatus(String taskId, String taskStatus, String errorno){
	    	if(errorno == null) errorno = "0";
	    	String sql = "update FD_Sync_Server_Task set taskStatus=?, updateTime=now(), errorno=? where taskId=?";
	    	Object[] values = {taskStatus, new Integer(errorno), taskId};
	    	jdbcDao.update(sql, values);
	    }
	    
	    public boolean isCancelSyncServerTask(String taskId){
	    	String sql = "select count(*) from FD_Sync_Server_Task where taskId=? and taskStatus like '%Cancel'";
	    	Object[] values = {taskId};
	    	long count = jdbcDao.queryForLong(sql, values);
	    	
	    	if(count > 0) return true;
	    	
	    	return false;
	    	
	    }
	    
	    public void updateSyncServerProcess(String taskId, String taskStatus, String totalCount, String finishCount, String errorno){
	    	if(errorno == null) errorno = "0";
	    	if(totalCount == null) totalCount = "0";
	    	if(finishCount == null) finishCount = "0";
	    	String sql = "update FD_Sync_Server_Task set taskStatus=?, totalTaskCount=?, finishTaskCount=?, errorno=?, updateTime=now() where taskId=?";
	    	Object[] values = {taskStatus, new Long(totalCount), new Long(finishCount), new Integer(errorno), taskId};
	    	jdbcDao.update(sql, values);
	    }
	    
	    /**
	     * 获取可以提供文件下载的机器列表
	     * @param serverIp
	     * @return
	     */
	    public List<String> getSyncServerSourceList(String serverIp){
			List<String> ipList = new ArrayList<String>();
			String sql = "select carryCompany, appSrv from FD_Down_Server where ip=?";
			Object[] values = {serverIp};
			Map server = jdbcDao.queryForMap(sql, values);
			if(server == null) return ipList;
			
			//查询相同运营商的机器
			sql = "select ip from FD_Down_Server where carryCompany=? and appSrv=? and ip!=? and dataFull=? limit 0, 100";
			values = new Object[]{server.get("carryCompany"), server.get("appSrv"), serverIp, "0"};
			List<Map> list = jdbcDao.queryForList(sql, values);
			
			if(!list.isEmpty()){
				for(Map map : list){
					ipList.add(map.get("ip").toString());
				}
			}		
			if(list.size() >= 5) return ipList;
			
			sql = "select ip from FD_Down_Server where carryCompany!=? and appSrv=? and ip!=? and dataFull=? limit 0, 100";
			list = jdbcDao.queryForList(sql, values);
			if(!list.isEmpty()){
				for(Map map : list){
					ipList.add(map.get("ip").toString());
				}
			}
			
			return ipList;
		}
	    
	    /**
	     * 获取客户与源服务器对应关系列表
	     * @param serverIp
	     * @return
	     */
	    public List<Map> getSyncServerCustomerSource(String serverIp){
	    	
	    	StringBuffer sb = new StringBuffer("select tmp.OPER_CODE as customer, tmp2.source as sourceServer " +
	    			"from FD_Down_Server ds, FD_Customer_Server cs,");	    	
	    	sb.append("(select a.OPER_CODE, b.customerId from PW_OPER a, FD_Customer b where a.OPER_CODE=b.entername ");
	    	sb.append(" union ");
	    	sb.append(" select a.OPER_CODE, b.customerId from PW_OPER a, FD_Customer b, FD_Account_Map c where ");
	    	sb.append(" a.OPER_CODE != b.entername and a.OPER_CODE=c.wsfdAccount and b.entername=c.cdnAccount ");
	    	sb.append(" and a.OPER_CODE not in('test','wsfdtest','admin')");
	    	sb.append(")tmp ,");	    	
	    	sb.append("(SELECT a.OPER_CODE, b.serverName as source from PW_OPER a, FD_Upload_Server b, FD_Customer_Uploadserver c ");
	    	sb.append(" where a.OPER_CODE=c.customerId and b.serverId=c.serverId and a.OPER_CODE not in('admin','test','wsfdtest')");
	    	sb.append(")tmp2 ");
	    	sb.append(" where ds.serverId=cs.serverId and cs.customerId=tmp.customerId ");
	    	sb.append(" and tmp.OPER_CODE=tmp2.OPER_CODE ");
	    	sb.append(" and ds.ip='");
	    	sb.append(serverIp);
	    	sb.append("'");    	
	    	
	    	return jdbcDao.queryForList(sb.toString());
	    }
	    
	    //===================================== 以下为新版本的相关查询 =======================================
	    
		/**
		 * 获取映射客户名，如果不存在映射关系，返回entername
		 * @param entername
		 * @return
		 */
		public String getMapEntername(String entername){
			String sql = "select cdnAccount from FD_Account_Map where wsfdAccount=?";
			Object[] values = {entername};
			Map map = jdbcDao.queryForMap(sql, values);
			if(map == null)
				return entername;
			return (String)map.get("cdnAccount");
		}
		
		/**
		 * 获取客户的所有源服务器
		 * @param customer
		 * @return
		 */
		public List<Map> getSourceServerByCustomer(String customer){
			String cdnAccount = this.getMapEntername(customer);
			String sql = "select serverIp, isMaster, dataFull from FD_Source_Server a, FD_Customer b where a.groupId=b.sourceGroup and b.entername=?";
			Object[] values = {cdnAccount};
			return jdbcDao.queryForList(sql, values);
		}
	    
	      
	    /**
	     * 根据url获取目录与频道的对应关系
	     * @param file 根据文件名称获取频道与目录的对应关系
	     * @return
	     */
	    public List<Map> getDirChannelMap(String file){
	    	String sql = "select dir, channel from FD_Dir_Channel where INSTR(?, dir) = 1";
	    	Object[] values  = {file}; 
	    	return jdbcDao.queryForList(sql, values);
	    }
	    
	    public Map getDirChannelByCustomer(String customerId){
	    	String sql = "select dir, channel from FD_Dir_Channel where customer = ? order by channel";
	    	Object[] values  = {customerId};
	    	List list=jdbcDao.queryForList(sql, values);
	    	if(null==list||0==list.size())
	    		return null;
	    	return (Map)list.get(0);
	    }
	    
	    /**
	     * 根据登陆用户获取上传服务器
	     * @param customer
	     * @return 如果不存在返回null
	     */
	    public Map getUploadServerByCustomer(String customer){
	    	String cdnAccount = this.getMapEntername(customer);
	    	if(cdnAccount == null)
	    		cdnAccount = customer;
	    	String sql = "select a.serverIp, a.sshUser, a.sshPwd,a.sshPort from FD_Source_Server a, FD_Customer b "
	    		+ "where a.groupId=b.sourceGroup and b.entername=? and a.isMaster=?";
	    	Object[] values = {cdnAccount, "0"};
	    	return jdbcDao.queryForMap(sql, values);
	    }
	    
	    public String getFtpPwdByCustomer(String customer){
	    	String sql = "select OPER_PWD from PW_OPER where OPER_CODE = ?";
	    	Object[] values = {customer};
	    	return jdbcDao.queryForMap(sql,values).get("OPER_PWD").toString();
	    }
	    
	    /**
	     * 根据某台源服务器IP获取同组的所有源服务器
	     * @param serverIp
	     * @return
	     */
	    public List<Map> getGroupSourceServers(String serverIp){
	    	String sql = "select a.serverIp, a.isp, a.isMaster, a.dataFull from FD_Source_Server a, FD_Source_Server b "+
	    	" where a.groupId=b.groupId and b.serverIp=? and a.serverIp !=b.serverIp";
	    	Object[] values = {serverIp};
	    	return jdbcDao.queryForList(sql, values);
	    }
	    
	    public String getSourceServerIsp(String serverIp){
	    	String sql = "select isp from FD_Source_Server where serverIp=?";
	    	Object[] values = {serverIp};
	    	Map map = jdbcDao.queryForMap(sql, values);
	    	if(map == null)
	    		return "6";
	    	return map.get("isp").toString();
	    }
	    
	    public List getAllSourceServer(){
	    	String sql = "select serverIp from FD_Source_Server order by serverIp";
	    	return jdbcDao.queryForList(sql);
	    }
	    
	    /**
	     * 获取源服务器上的所有ftp用户
	     * @param serverIp
	     * @return
	     */
	    public String[] getAllFtpUsers(String serverIp){
	    	StringBuffer sql = new StringBuffer("select tmp.wsfdAccount as ftpUser from ");	    	
	    	sql.append("(select oper.OPER_CODE as wsfdAccount,")
	    	.append(" if(map.cdnAccount is null, oper.OPER_CODE, map.cdnAccount) as cdnAccount ")
	    	.append("from PW_OPER oper LEFT join FD_Account_Map map on oper.OPER_CODE=map.wsfdAccount) tmp,")
	    	.append("FD_Source_Server ss, FD_Customer cs ")
	    	.append("where tmp.cdnAccount=cs.entername and ss.groupId=cs.sourceGroup and ss.serverIp=?");
	    	Object[] values = {serverIp};
	    	List<Map> list = jdbcDao.queryForList(sql.toString(), values);
	    	if(list.isEmpty()){
	    		return null;
	    	}else{
	    		String[] users = new String[list.size()];
	    		for(int i=0; i<list.size(); i++){
	    			users[i] = (String)list.get(i).get("ftpUser");
	    		}
	    		return users;
	    	}
	    }
	    
	    public Map getSourceServerInfo(String serverIp){
	    	String sql = "select sshUser, sshPort, sshPwd from FD_Source_Server where serverIp=?";
	    	Object[] values = {serverIp};
	    	return jdbcDao.queryForMap(sql, values);
	    }
	    
	    public List getBakServerInfo(String customer,String serverIp){
	    	String cdnAccount = this.getMapEntername(customer);
	    	String sql="select a.serverIP, a.sshUser, a.sshPort, a.sshPwd from FD_Source_Server a, FD_Customer b where a.groupId=b.sourceGroup and b.entername=? and a.serverIp<>?";
	    	Object[] values={cdnAccount,serverIp};
	    	return jdbcDao.queryForList(sql, values);
	    }
	    
	    /**
	   	 * 查询操作日志
	   	 * @param hs
	   	 * @return
	   	 */
		    public void getActionLog(Map hs,PageInfo page){
			List<Object> params = new ArrayList<Object>();
			StringBuffer sql = new StringBuffer("SELECT * FROM PW_ACTION_LOG");
			sql.append(" WHERE 1=1 ");
			String operName = (String)hs.get("operName");
			if(StringUtils.isNotEmpty(operName)){
			    sql.append(" AND OPER_NAME LIKE ? ");
			    params.add("%"+operName+"%");
			}
			String keyWord = (String)hs.get("keyWord");
			if(StringUtils.isNotEmpty(keyWord)){
			    sql.append(" AND ACTION_LOG LIKE ? ");
			    params.add("%"+keyWord+"%");
			}
			String startTime = (String)hs.get("startTime");
			String endTime=(String)(String)hs.get("endTime");
			if(StringUtils.isNotEmpty(startTime))
				startTime +=" 00:00:00";
			if(StringUtils.isNotEmpty(endTime))
			   endTime +=" 24:00:00";
			if(StringUtils.isNotEmpty(startTime)&&StringUtils.isNotEmpty(endTime)){
			    sql.append(" AND ACTION_TIME >= ? AND ACTION_TIME <= ?");
			    params.add(startTime);
			    params.add(endTime);
			}else if(StringUtils.isEmpty(startTime)&&StringUtils.isNotEmpty(endTime)){
				sql.append(" AND ACTION_TIME <= ?");
			    params.add(endTime);
			}else if(StringUtils.isNotEmpty(startTime)&&StringUtils.isEmpty(endTime)){
				sql.append(" AND ACTION_TIME >= ?");
			    params.add(startTime);
			}
			sql.append(" ORDER BY ACTION_TIME DESC");	
			log.logDebug("ServerInfo SQL:" + sql.toString()+params);
			QuerySql qs = new QuerySql(sql);
			qs.setValues(params);
			jdbcDao.queryForPage(page, qs);		
		    }
		    


		    
    /**
     * 判断任务是否可以重启
     * @param taskId
     * @return
     */
    public boolean canReRunTask(String taskId) {
        FdTaskList task = getTaskById(taskId);
        if (task == null) {
            // 任务可能已经被删除
            log.logInfo("can't reStart task [taskid=" + taskId
                    + "],task is not exist!");
            return false;
        }

        // 只有failure、stop、operator的任务才能重启
        if (!Constants.TASK_STATUS_FAILURE.equals(task.getTaskStatus())
                && !Constants.TASK_STATUS_STOP.equals(task.getTaskStatus())
                && !Constants.TASK_STATUS_OPERATOR.equals(task.getTaskStatus())) {
            log.logInfo("can't reStart task [taskid=" + taskId + ",taskStatus="
                    + task.getTaskStatus() + "].");
            return false;
        }

        // upload、deCompress的任务可以重启
        if (Constants.TASK_KIND_UPLOAD.equals(task.getTaskKind())
                || Constants.TASK_KIND_DECOMPRESS.equals(task.getTaskKind())) {
            log.logInfo("can reStart task [taskid=" + taskId + ",taskKind="
                    + task.getTaskKind() + "].");
            return true;
        }

        // mkdir、rename、delete任务不能重启
        else if (Constants.TASK_KIND_MKDIR.equals(task.getTaskKind())
                || Constants.TASK_KIND_RENAME.equals(task.getTaskKind())
                || Constants.TASK_KIND_DELETE.equals(task.getTaskKind())) {

            // 假设任务为：把文件名a重命名为b。如果在此任务之后，有任何文件名或新文件名为a或b的任务，则不能重启
            log.logInfo("canreStart task [taskid=" + taskId + ",taskKind="
                    + task.getTaskKind() + ",taskStatus="
                    + task.getTaskStatus() + "].");
            return false;
        }

        // 其他任务或异常的类型都不能重启
        return false;
    }

    /**
     * 根据任务ID获取获取信息
     * 
     * @param taskId
     * @return
     */
    public FdTaskList getTaskById(String taskId) {
        if (StringUtils.isEmpty(taskId)) {
            throw new RuntimeException("taskId is Empty!");
        }
        return (FdTaskList) hiberDao.get(FdTaskList.class, taskId);
    }
		    

    /**
     * 重新启动任务
     * @param taskIds 任务列表
     */
    public void restartSyncTask(String[] taskIds) {
        List<String> sqls = new ArrayList<String>();
        if (null == taskIds || 0 == taskIds.length) {
            return;
        }

        List<String> canReRunIdList = new ArrayList<String>();
        for (final String taskId : taskIds) {
            if (canReRunTask(taskId)) {
                canReRunIdList.add(taskId);
            }
        }

        if (!canReRunIdList.isEmpty()) {
            StringBuffer sql_detail = new StringBuffer(
                    "delete from FD_Task_Detail WHERE 1<>1 ");
            for (String id : canReRunIdList) {
                sql_detail.append(" OR taskId = '" + id + "'");
            }
            sqls.add(sql_detail.toString());

            StringBuffer sql = new StringBuffer(
                    "UPDATE FD_Task_List SET taskStatus='" + Constants.TASK_STATUS_WAIT + "' WHERE taskId in (");
            for (String id : canReRunIdList) {
                sql.append("'" + id + "',");
            }
            // sql.deleteCharAt(sql.length()-1);
            sql.replace(sql.length() - 1, sql.length(), ")");
            sql.append("and taskStatus in ('" + Constants.TASK_STATUS_STOP + "','" + Constants.TASK_STATUS_FAILURE + "', '" + Constants.TASK_STATUS_OPERATOR + "')");
            sqls.add(sql.toString());
            log.logInfo("Restart task SQL:" + sql.toString());
            jdbcDao.batchUpdate(sqls);
        }
    }
    
    /**
     * 标记任务为“运维处理”状态
     * @param taskIdList
     */
    public void setOperatorTask(String[] taskIds) {
        List<String> sqls = new ArrayList<String>();
        if (null == taskIds || 0 == taskIds.length) {
            return;
        }

        StringBuffer sql = new StringBuffer(
                "UPDATE FD_Task_List SET taskStatus='"
                        + Constants.TASK_STATUS_OPERATOR
                        + "' WHERE taskId in (");
        for (String id : taskIds) {
            sql.append("'" + id + "',");
        }
        sql.replace(sql.length() - 1, sql.length(), ")");
        sql.append("and taskStatus in ('stop','failure')");
        sqls.add(sql.toString());
        log.logInfo("set operator task SQL:" + sql.toString());
        jdbcDao.batchUpdate(sqls);
    }
    
    /**
     * 查询需要向smg客户汇报的记录
     * @param count  每次获取的记录数
     * @param maxOverTime  时间间隔
     * @return
     */
    public List querySmgReportTaskList(String customerName, int count, int maxOverTime){
        String sql = "select taskId,filename,taskStatus,taskKind  from FD_Task_List t where entername=? and (isReport not in ('F', 'S') or isReport is null) and ((taskKind in ('upload','rename','mkdir','delete') and taskStatus in('failure','stop')  and UNIX_TIMESTAMP(timestamp)<UNIX_TIMESTAMP()-?) or (taskStatus='success' and taskKind in ('upload','rename','mkdir','delete','md5failure')) or (taskStatus='failure' and taskKind='md5failure'))  limit ?";
//        String sql = "select taskId,filename,taskStatus,taskKind  from FD_Task_List t where entername='smg' and ((taskKind in ('upload','rename','mkdir','delete') and taskStatus in('failure','stop') and (isReport not in('S', 'F') or isReport is null) and UNIX_TIMESTAMP(timestamp)<UNIX_TIMESTAMP()-?) or (taskStatus='success' and taskKind in ('upload','rename','mkdir','delete','md5failure') and (isReport <> 'S' or isReport is null)) or (taskStatus='failure' and taskKind='md5failure' and (isReport not in('S', 'F') or isReport is null))) limit ?";
       // String hql = "from FdTaskList t where entername='smg' and ((taskKind in ('upload','rename','mkdir','delete') and taskStatus in('failure','stop') and (isReport not in('S', 'F') or isReport is null) and UNIX_TIMESTAMP(timestamp)<UNIX_TIMESTAMP()-$maxOverTime) or (taskStatus='success' and taskKind in ('upload','rename','mkdir','delete','md5failure') and (isReport <> 'S' or isReport is null)) or (taskStatus='failure' and taskKind='md5failure' and (isReport not in('S', 'F') or isReport is null))) limit 30";
        return jdbcDao.queryForList(sql, new Object[]{customerName, count, maxOverTime});
    }
    
    /**
     * 根据反馈结果更新数据库
     * @param reportStatus
     * @param taskIdList
     */
    public void updateTaskReportInfo(String reportStatus, List<String> taskIdList){
        if(taskIdList == null || taskIdList.isEmpty()){
            return;
        }
        StringBuffer sql = new StringBuffer("update FD_Task_List set isReport='" + reportStatus + "' where taskId in (");
        for(int i=0; i<taskIdList.size()-1; i++){
            sql.append("'" + taskIdList.get(i) + "',");
        }
        sql.append("'" + taskIdList.get(taskIdList.size()-1) + "')");
        log.logInfo("updateTaskReportInfo sql:" + sql);
        jdbcDao.update(sql.toString());
    }
   
    
    /**
     * 获取用户今天同步的文件数
     * @param entername
     * @param taskStatus
     * @return
     */
    public long getTodaySyncTaskByCustomerAndStatus(String entername, String taskStatus){
        String sql = "select count(*) as taskCount from FD_Task_List where entername=? and syncStartTime>? and taskKind=? and taskStatus=?";
        Object[] values = {entername, java.sql.Date.valueOf(DateUtil.getCurrentDate()), Constants.TASK_KIND_UPLOAD, taskStatus};
        return jdbcDao.queryForLong(sql, values);
    }
    
    /**
     * 获取用户今天同步成功的文件数
     * @param entername
     * @param taskStatus
     * @return
     */
    public long getTodaySyncSuccessTaskByCustomerAndStatus(String entername){
        return getTodaySyncTaskByCustomerAndStatus(entername, Constants.TASK_STATUS_SUCCESS);
    }
    
    /**
     * 根据客户查询客户未发送邮件的任务
     * @param entername
     * @param mailStatus
     * @param syncEndTime
     * @return
     */
    public List queryCustMailTaskList(String entername, String mailStatus, Timestamp syncEndTime){
        String sql = "select * from FD_Task_List t where t.entername=? and (t.createTime>=? or t.syncEndTime>=? or t.taskStatus in (?, ?))";
        return jdbcDao.queryForList(sql, new Object[]{entername, syncEndTime, syncEndTime, Constants.TASK_STATUS_WAIT, Constants.TASK_STATUS_RUN});
    }
    
    /**
     * 根据客户查询系统（客服等）未发送邮件的任务
     * @param entername
     * @param mailStatus
     * @param syncEndTime
     * @return
     */
    public List querySysMailTaskList(String entername, String mailStatus, Timestamp syncEndTime){
        String sql = "select * from FD_Task_List t where t.entername=? and (t.createTime>=? or t.syncEndTime>=? or t.taskStatus in (?, ?))";
        return jdbcDao.queryForList(sql, new Object[]{entername, syncEndTime, syncEndTime, Constants.TASK_STATUS_WAIT, Constants.TASK_STATUS_RUN});
    }
    
    /**
     * 更新客户邮件发送状态
     * @param taskIdList
     * @param mailStatus
     */
    public void updateCustMailStatus(List<String> taskIdList, String mailStatus){
        StringBuffer sql = new StringBuffer("update FD_Task_List set custMailStatus = ? where taskId in(");
        for(int i=0; i<taskIdList.size()-1; i++){
            sql.append("'" + taskIdList.get(i) + "', "); 
        }
        sql.append("'" + taskIdList.get(taskIdList.size()-1) + "')");
        Object[] values = {mailStatus};
        jdbcDao.update(sql.toString(), values);
    }
    
    /**
     * 更新系统（客服等）邮件发送状态
     * @param taskIdList
     * @param mailStatus
     */
    public void updateSysMailStatus(List<String> taskIdList, String mailStatus){
        StringBuffer sql = new StringBuffer("update FD_Task_List set sysMailStatus = ? where taskId in(");
        for(int i=0; i<taskIdList.size()-1; i++){
            sql.append("'" + taskIdList.get(i) + "', "); 
        }
        sql.append("'" + taskIdList.get(taskIdList.size()-1) + "')");
        Object[] values = {mailStatus};
        jdbcDao.update(sql.toString(), values);
    }
    
    /**
     * 更新系统（客服等）邮件发送状态
     * @param taskIdList
     * @param mailStatus
     */
    public List queryMailConfigList(){
        String sql = "select customer, sys_mail, cust_mail, sys_mail_interval, cust_mail_interval from FD_Cust_Mail_Config ";
        return jdbcDao.queryForList(sql);
    }
    
    /**
     * 从系统表中获取参数值
     * @param paramCode
     * @return
     */
    public String getParamValueSysConfig(String paramCode){
        String sql = "select PARAM_VALUE  from PW_SYS_CONFIG where PARAM_CODE=?";
        List list = jdbcDao.queryForList(sql, new Object[]{paramCode});
        if(list == null || list.isEmpty()){
            return null;
        }
        Map data = (Map)list.get(0);
        return (String)data.get("PARAM_VALUE");
    }
    
    /**
     * 从用户表中获取用户可查询的客户列表信息
     * @param paramCode
     * @return
     */
    public String getQueryOpersFromOper(String oper){
        String sql = "select QUERY_OPERS from PW_OPER  where OPER_CODE=?";
        List list = jdbcDao.queryForList(sql, new Object[]{oper});
        if(list == null || list.isEmpty()){
            return null;
        }
        Map data = (Map)list.get(0);
        return (String)data.get("QUERY_OPERS");
    }
    
    /**
     * 从用户表中查询所有客户的可查询客户列表信息
     * @param paramCode
     * @return
     */
    public Map<String, String> queryAllQueryOpers(){
        String sql = "select OPER_CODE, QUERY_OPERS from PW_OPER ";
        List list = jdbcDao.queryForList(sql);
        Map<String, String> queryOpersMap= new HashMap<String, String>();
        if(list == null || list.isEmpty()){
            return queryOpersMap;
        }
        for(int i=0; i<list.size(); i++){
            Map data = (Map)list.get(i); 
            queryOpersMap.put((String)data.get("OPER_CODE"), (String)data.get("QUERY_OPERS"));
        }
        
        return queryOpersMap;
    }
    
    /**
     * 获取系统参数
     * @param paramCode
     * @return
     */
    public List querySysConfig(){
        String sql = "select PARAM_CODE, PARAM_VALUE  from PW_SYS_CONFIG ";
        return jdbcDao.queryForList(sql);
    }
    
    
    
    /**
     * 根据任务ID查询已经同步的机器数
     * @param taskId
     * @return
     */
    public int getSyncServerCount(String taskId){
        String sql = "SELECT COUNT(syncStatus) as syncServerCount FROM FD_Task_Detail a WHERE a.taskId = ? AND a.syncStatus = 'hasSync'";
        List<String> params = new ArrayList<String>();
        params.add(taskId);  
        Map map = jdbcDao.queryForMap(sql,params.toArray());
        Long syncServerCount = (Long)map.get("syncServerCount");
        return syncServerCount.intValue();
    }
    
  
    
    /**
     * 更新任务的反馈标志
     * 
     * @param taskList
     */
    public void updateTaskReportStatus(List<FdTaskList> taskList) {
        if (taskList != null && !taskList.isEmpty()) {
            String[] sqls = new String[taskList.size()];
            FdTaskList task = null;
            for (int i = 0; i < taskList.size(); i++) {
                task = taskList.get(i);
                sqls[i] = "update FD_Task_List set isReport='"
                        + task.getIsReport() + "' where taskId='"
                        + task.getTaskId() + "';";
            }
            jdbcDao.batchUpdate(sqls);
        }
    }
    
    /**
     * 更新任务的推送标志
     * 
     * @param taskList
     */
    public void updatePurgeReportStatus(List<FdTaskList> taskList) {
        if (taskList != null && !taskList.isEmpty()) {
            String[] sqls = new String[taskList.size()];
            FdTaskList task = null;
            for (int i = 0; i < taskList.size(); i++) {
                task = taskList.get(i);
                sqls[i] = "update FD_Task_List set isPurge='"
                        + task.getIsPurge() + "' where taskId='"
                        + task.getTaskId() + "';";
            }
            jdbcDao.batchUpdate(sqls);
        }
    }
    
    /**
     * 查询路由表信息
     * @return
     */
    public List<FdRouteMap> queryRouteMapList(){
        String hql = "from FdRouteMap ";
        return hiberDao.find(hql);        
    }
    
    

}